import numpy as np
import pyqtgraph as pg
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QCheckBox

from AdbUtils import adb_get_devices
from AppGlobal import AppGlobal
from MainWindow import Ui_MainWindow
from Monitor import Monitor, MonitorTop


class MonitorWindow(QMainWindow):

    def __init__(self, parent=None):
        super(MonitorWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.pgWidget = pg.GraphicsLayoutWidget()
        self.ui.verticalLayout_2.addWidget(self.pgWidget)
        self.Monitor = None
        self.isPause = False
        self.pgList = {}

    def stopMonitor(self):
        if self.Monitor:
            self.Monitor.setExitFlag()
            self.Monitor = None

    def startMonitor(self):
        if self.Monitor is None:
            self.Monitor = Monitor()
            self.Monitor.start()

        m_info = MonitorTop(self.refreshData)
        self.Monitor.addMonitor(m_info)

    def refreshData(self, data_dict):
        if self.isPause:
            return

        keys = data_dict.keys()
        count = self.ui.verticalLayout_ProcessList.count()

        for key in keys:
            has = False
            for i in range(count):
                box = self.ui.verticalLayout_ProcessList.itemAt(i)
                if key == box.widget().text():
                    has = True
                    break
            if not has:
                box = WarpQCheckBox()
                box.setText(key)
                box.change.connect(self.onCheckChange)
                self.ui.verticalLayout_ProcessList.addWidget(box)

            temp = self.pgList.get(key)
            if temp:
                temp["p_cpu"].setData(data_dict[key]["cpu"])
                title = "CPU-%s avr=%.2f" % (key, np.mean(data_dict[key]["cpu"]))
                temp["plot_cpu"].setTitle(title)
                temp["p_mem"].setData(data_dict[key]["rss"])
                title = "MEMORY-%s avr=%.2f" % (key, np.mean(data_dict[key]["rss"]))
                temp["plot_mem"].setTitle(title)

    def onCheckBoxPause(self, is_pause):
        self.isPause = is_pause

    def onBtnExportExcel(self):
        pass

    def onCheckChange(self, name, is_check):
        plot = self.pgList.get(name)
        if is_check:
            if plot is None:
                plot_mem = self.pgWidget.addPlot(title="MEMORY-" + name)
                plot_mem.showGrid(x=True, y=True)
                p_mem = plot_mem.plot(pen=(255, 0, 0), name="mem-" + name)
                plot_cpu = self.pgWidget.addPlot(title="CPU-" + name)
                plot_cpu.showGrid(x=True, y=True)
                p_cpu = plot_cpu.plot(pen=(255, 0, 0), name="cpu-" + name)
                self.pgList[name] = {"plot_mem": plot_mem, "p_mem": p_mem, "plot_cpu": plot_cpu, "p_cpu": p_cpu}
                self.pgWidget.nextRow()
        else:
            if plot:
                temp = self.pgList.pop(name)
                self.pgWidget.removeItem(temp["plot_mem"])
                self.pgWidget.removeItem(temp["plot_cpu"])

    def onBtnRefreshDevice(self):
        devices = adb_get_devices()
        cur_device = AppGlobal().get_device()
        if not devices or len(devices) <= 0:
            self.stopMonitor()
            AppGlobal().set_device(None)
            return

        if cur_device not in devices:
            self.stopMonitor()
            self.ui.comboBox_Device.clear()
            for dev in devices:
                self.ui.comboBox_Device.addItem(dev["serial"])
            self.ui.comboBox_Device.setCurrentIndex(0)
        else:
            for dev in devices:
                has = False
                for i in range(self.ui.comboBox_Device.count()):
                    if dev == self.ui.comboBox_Device.itemText(i):
                        has = True
                        break
                if not has:
                    self.ui.comboBox_Device.addItem(dev)

    def onDeviceChanged(self, device):
        AppGlobal().set_device(device)
        self.startMonitor()


class WarpQCheckBox(QCheckBox):
    change = pyqtSignal(str, bool)

    def __init__(self):
        super().__init__()
        self.toggled['bool'].connect(self.checkChange)

    def checkChange(self, is_check):
        self.change.emit(self.text(), is_check)


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    window = MonitorWindow()
    window.setWindowTitle('Monitor')
    window.show()
    sys.exit(app.exec_())
